package org.example.controller;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.example.Mapper.ActivityMapper;
import org.example.Mapper.ActivityRecordMapper;
import org.example.Mapper.ExcelRecordMapper;
import org.example.Mapper.UserMapper;
import org.example.domain.*;
import org.example.service.impl.ApplyRecordServiceImpl;
import org.example.untils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

@RestController
@RequestMapping("applyRecord")
public class ApplyRecordController {

    @Autowired
    private ApplyRecordServiceImpl applyRecordServiceImpl;

    @Autowired//工期较赶，此处较为生疏，为了方便，就不再分层处理了。
    private UserMapper userMapper;

    @Autowired
    private ActivityRecordMapper activityRecordMapper;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private ExcelRecordMapper excelRecordMapper;

    @PostMapping("/addApplyRecord")
    public Result addApplyRecord(@RequestBody ApplyRecord applyRecord){
        System.out.println(applyRecord);
        applyRecordServiceImpl.addApplyRecord(applyRecord);
        return new Result(200,"申请成功",null);
    }

    @GetMapping("/getApplyRecords")
    public Result getApplyRecords(){
        ApplyRecord[] applyRecords= applyRecordServiceImpl.getApplyRecords();
        return new Result(200,"获取成功",applyRecords);
    }

    @GetMapping("/beforeGetExcel")
    public Result beforeGetExcel(){//导出前校验是否为空表
        User[] users=userMapper.getUserBySt();//获取所有素拓不为0的学生
        if(users.length==0){
            return new Result(201,"表格为空",null);
        } else {
            return new Result(200,"",null);
        }

    }

    @GetMapping("/getExcel")
    public ResponseEntity<byte[]> getExcel(HttpServletResponse response) throws IOException {
        // 创建一个新的Excel工作簿
        Workbook workbook = new HSSFWorkbook();
        // 创建一个工作表
        Sheet sheet = workbook.createSheet("Sheet1");
        // 创建行和单元格，并填充数据
        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);
        cell.setCellValue("姓名");
        cell = row.createCell(1);
        cell.setCellValue("学号");
        cell = row.createCell(2);
        cell.setCellValue("班级");
        cell = row.createCell(3);
        cell.setCellValue("其他素拓");
        cell = row.createCell(4);
        cell.setCellValue("思政培根");
        cell = row.createCell(5);
        cell.setCellValue("学科启智");
        cell = row.createCell(6);
        cell.setCellValue("体育强魄");
        cell = row.createCell(7);
        cell.setCellValue("美育润心");
        cell = row.createCell(8);
        cell.setCellValue("劳动强基");
        cell = row.createCell(9);
        cell.setCellValue("创新创业");
        User[] users=userMapper.getUserBySt();//获取所有素拓不为0的学生
        for(int i=0;i<users.length;i++){
            row = sheet.createRow(i+1);
            cell = row.createCell(0);
            cell.setCellValue(users[i].getName());
            cell = row.createCell(1);
            cell.setCellValue(users[i].getAccount());
            cell = row.createCell(2);
            cell.setCellValue(users[i].getClassName());
            cell = row.createCell(3);
            cell.setCellValue(users[i].getP_st());
            cell = row.createCell(4);
            cell.setCellValue(users[i].getP_st_szpg());
            cell = row.createCell(5);
            cell.setCellValue(users[i].getP_st_xkqz());
            cell = row.createCell(6);
            cell.setCellValue(users[i].getP_st_tyqp());
            cell = row.createCell(7);
            cell.setCellValue(users[i].getP_st_myrx());
            cell = row.createCell(8);
            cell.setCellValue(users[i].getP_st_ldqj());
            cell = row.createCell(9);
            cell.setCellValue(users[i].getP_st_cxcy());
        }
        // 将Excel文件写入字节数组输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        outputStream.close();
        // 设置响应头，告诉浏览器返回的是一个Excel文件
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", "申请素拓.xlsx");
        // 返回Excel文件的字节数组
        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(outputStream.toByteArray());
    }

    @GetMapping("/makeSureDownExcelOk")
    public Result makeSureDownExcelOk(){//确保下载成功以后将学生的素拓清零，并追加记录，修改最近的一次素拓
        User[] users=userMapper.getUserBySt();//获取所有素拓不为0的学生
        userMapper.changeUserLast_p_st();//将即将清0的学生素拓分数保留最近一次记录
        ExcelRecord lastExcelRecord=excelRecordMapper.getLastExcelRecordIndex();//获取最后一条数据
        Integer orderNumber;
        if(lastExcelRecord==null){
            orderNumber=1;
        } else {
            orderNumber=lastExcelRecord.getOrderNumber()+1;
        }
        for (User user : users) {
            ExcelRecord excelRecord = new ExcelRecord();
            //向excel导出记录内追加数据
            excelRecord.setOrderNumber(orderNumber);
            excelRecord.setName(user.getName());
            excelRecord.setAccount(user.getAccount());
            excelRecord.setP_st(user.getP_st());
            excelRecord.setP_st_szpg(user.getP_st_szpg());
            excelRecord.setP_st_xkqz(user.getP_st_xkqz());
            excelRecord.setP_st_tyqp(user.getP_st_tyqp());
            excelRecord.setP_st_myrx(user.getP_st_myrx());
            excelRecord.setP_st_ldqj(user.getP_st_ldqj());
            excelRecord.setP_st_cxcy(user.getP_st_cxcy());
            excelRecordMapper.addOneExcelRecord(excelRecord.getOrderNumber(), excelRecord.getName(),
                    excelRecord.getAccount(), excelRecord.getP_st(),excelRecord.getP_st_szpg(),
                    excelRecord.getP_st_xkqz(),excelRecord.getP_st_tyqp(),excelRecord.getP_st_myrx(),
                    excelRecord.getP_st_ldqj(),excelRecord.getP_st_cxcy());
        }
        userMapper.updateUserStToZero();//获取完成以后，立马将所有同学的素拓清零
        return new Result();
    }

    @PostMapping("/accessApply")
    public Result accessApply(@RequestBody() ApplyRecord applyRecord,@RequestParam("tag") Integer tag){
        Integer result=applyRecordServiceImpl.accessApply(applyRecord,tag);
        if(result==0){
            return new Result(200,"已被他人处理",null);
        } else {
            return new Result(200,"已通过",null);
        }
    }

    @PostMapping("/refuseApply")
    public Result refuseApply(@RequestBody() ApplyRecord applyRecord){
        Integer result=applyRecordServiceImpl.refuseApply(applyRecord);
        if(result==0){
            return new Result(200,"已被他人处理",null);
        } else {
            return new Result(200,"已拒绝",null);
        }
    }

    @PostMapping("/preUploadExcel")//管理员上传签到表先进行预签到判断
    public Result preUploadExcel(MultipartFile excel,Integer activityId) throws IOException {
        int[] results=new int[3];//分别记录此次活动应到多少人，实到多少人，缺席多少人
        ArrayList<String> accounts = getAccounts(excel);
        if(accounts.get(0).equals("201")){//无法读取到表格内的数据，签到失败
            return new Result(201,"签到失败",results);
        }
        ArrayList<Integer> userIds=new ArrayList<>();//签到名单内学生们的id
        for (String account : accounts) {
            User user= userMapper.login(account);
            if(user==null){//未查询到该学号学生时直接跳过，并将其添加至错误的行数
                continue;
            }
            userIds.add(user.getId());
        }
        ActivityRecord[] activityRecords= activityRecordMapper.getActivityRecordsByActivityId(activityId);//获取到该项活动
        // 的参加记录
        results[0]=activityRecords.length;//本次活动应到多少人
        for (ActivityRecord activityRecord : activityRecords) {//遍历该次活动所有报了名的学生
            boolean isDo=false;//默认设置该名学生未签到
            for (Integer userId : userIds) {
                if (Objects.equals(userId, activityRecord.getUserId())){//该学生报名并参加了这项活动，
                    // 为其这一条活动记录设置为已签到
                    isDo=true;//设置该名学生签到了
                    results[1]++;//签到的人数加一
                    break;
                }
            }
            if(!isDo){//遍历完签到名单都没有发现该学生id，说明其缺席了这次活动
                results[2]++;//未签到的人数加一
            }
        }
        return new Result(200,"签到成功",results);
    }

    private static ArrayList<String> getAccounts(MultipartFile excel) throws IOException {//获取学生账号
        Workbook workbook = new XSSFWorkbook(excel.getInputStream());
        Sheet sheet=workbook.getSheetAt(0);//获取表
        Row row;//行
        Cell cell;
        ArrayList<String> accounts=new ArrayList<>();
        for(int i=0;i<sheet.getPhysicalNumberOfRows();i++){//获取表内的学号
            row = sheet.getRow(i);//获取第i行数据
            if(row==null){
                accounts.add("201");
                return accounts;
            }
            cell=row.getCell(0);
            StringBuilder account= new StringBuilder(cell.toString().replaceAll("\\.", "")
                    .replaceAll("E9", ""));
            //去除格式转换留下的无效字符
            if(account.length()!=10){//尾号出现了0，对其循环补0
                for (int j=account.length();j<10;j++){
                    account.append("0");
                }
            }
            accounts.add(account.toString());
        }
        return accounts;
    }

    @PostMapping("/uploadExcel")//管理员上传签到表
    public Result uploadExcel(MultipartFile excel,Integer activityId) throws IOException {
        Activity activity=activityMapper.getAllById(activityId);
        if(activity.getIsSignIn()==1){//已经进行过了签到
            return new Result(201,"此次活动已签到",null);
        }
        ArrayList<String> accounts = getAccounts(excel);
        ArrayList<Integer> userIds=new ArrayList<>();//签到名单内学生们的id
        for (String account : accounts) {
            User user= userMapper.login(account);
            if(user==null){//未查询到该学号学生时直接跳过
                continue;
            }
            userIds.add(user.getId());
        }
        ActivityRecord[] activityRecords= activityRecordMapper.getActivityRecordsByActivityId(activityId);//获取到该项活动
        // 的参加记录
        for (ActivityRecord activityRecord : activityRecords) {//遍历该次活动所有报了名的学生
            boolean isDo=false;//默认设置该名学生未签到
            for (Integer userId : userIds) {
                if (Objects.equals(userId, activityRecord.getUserId())){//该学生报名并参加了这项活动，为其这一条活动记录设置为已签到
                    activityRecordMapper.changeIsDoToOneById(activityRecord.getId());//将此次活动记录设置为已签到
                    isDo=true;//设置该名学生签到了
                    break;
                }
            }
            if(!isDo){//遍历完签到名单都没有发现该学生id，说明其缺席了这次活动
                activityRecordMapper.changeIsDoToTwoById(activityRecord.getId());//将此次活动设置为未签到（缺席）
                ActivityRecord[] activityRecords1=activityRecordMapper
                        .getAllActivityRecordsByIsDoAndIsPunishAndUserId(activityRecord.getUserId());//获取这条活动记录的
                // 报名者目前有几条还未被处罚的记录
                if(activityRecords1.length==3){//未处罚的记录到达了三条，对其进行处罚
                    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Calendar calendar=Calendar.getInstance();//获取日历
                    calendar.setTime(new Date());
                    calendar.add(Calendar.DATE,90);
                    userMapper.changePunishDateById(activityRecord.getUserId(),
                            calendar.getTime());//对该学生做出三个月不能报名任何活动的处罚
                    activityRecordMapper.changeIsPunishToOneByUserId(activityRecord.getUserId());//处罚后将缺席的记录标记未
                    // 已经处罚了
                }
            }
        }
        activityMapper.changeIsSignInById(activityId);//标记此次活动已签到
        return new Result(200,"签到成功",null);
    }

    @GetMapping("/getApplyRecordsByUserId")
    public Result getApplyRecordsByUserId(Integer userId,Integer start){
        ApplyRecord[] applyRecords= applyRecordServiceImpl.getApplyRecordsByUserId(userId,start);
        return new Result(200,"获取成功~",applyRecords);
    }
}
